<?php
namespace Bundle\ModuleBundle;

class EntityGenerator
{
    private $_namespace;
    private $_class;
    private $_baseClass;

    /**
     * Массив полей класса
     */
    private $_fields;
    /**
     * 
     */
    private $_methods;
    /**
     * Массив мета описаний
     */
    private $_meta;

    private $_tableName;

    public function __construct($className, $tableName)
    {

        $this->_namespace = \substr($className,0,  \strrpos($className, '\\'));
        $this->_class = \substr($className, \strrpos($className, '\\') + 1);

        $this->_tableName = $tableName;

        $this->_baseClass = "\\Bundle\\ModuleBundle\\Entities\\BaseEntity";

        $this->_fields = array();
        $this->_methods = array();
        $this->_meta = array();


    }

    public function getFullClassName()
    {
        return $this->_class;
    }

    public function getCode($eval = false)
    {
        if(!$eval)
        $result = <<<EOF
<?php
/*
* Generated model *
*/

EOF;
        else
            $result = '';
        
        $result .= $this->getAnnotation();
        $result .= $this->getFields();
        $result .= $this->getMethods();
        $result .= $this->getMapping();
        $result .= $this->getFooter();

        return $result;
    }

    public function addField($name, $mapping)
    {
        $this->_fields [] = $name;
        $this->_methods[$name] ['get'] = $this->generateGetter($name);
        $this->_methods[$name] ['set'] = $this->generateSetter($name);

        $this->_meta [$name] = $mapping;
    }

    private function generateGetter($name)
    {
        return \sprintf("\tpublic function get%s()\n\t{\n\t\treturn \$this->$name;\n\t}\n", \ucfirst($name));
    }

    private function generateSetter($name)
    {
        return \sprintf("\tpublic function set%s(\$$name)\n\t{\n\t\t\$this->$name = \$$name;\n\t}\n", \ucfirst($name));
    }

    private function getAnnotation()
    {
        return <<<EOF
namespace {$this->_namespace};
/**
* Class "{$this->_class}".
*/
class {$this->_class} extends {$this->_baseClass}
{

EOF;
    }

    private function getFields()
    {
        $fields = '';
        foreach($this->_fields as $field)
        {
            $fields .= \sprintf("\tprivate \$%s;\n", $field);
        }
        return $fields;
    }

    private function getMethods()
    {
        $methods = '';
        foreach($this->_methods as $method)
        {
            $methods .= $method['get'];
            $methods .= $method['set'];
        }

        return $methods;
    }

    private function getMapping()
    {
        $mapping = <<<EOF
        public static function loadMetadata(\\Doctrine\\ORM\\Mapping\\ClassMetadata \$metadata)
        {
            \$metadata->setTableName("{$this->_tableName}");

EOF;
        foreach($this->_meta as $meta)
        {
            $mapping .= \sprintf("\t    \$metadata->mapField(%s);\n", \var_export($meta, true));
        }

        $mapping .= "\t}\n";
        return $mapping;
    }

    private function getFooter()
    {
        return sprintf("}\n// Generated at. %s", \date("D, d M Y H:i:s"));
    }
}
?>
